﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using TI;
using System.Net;
using System.IO;
using MongoDB;
using Helper;
using TiEntityObject.Transport;

namespace MergeTI.TiDocumentProcessor
{
    //задача организовать скачивание  заданной колеекции 
    public class FastDocLoader
    {      
        public static TransportConfig config = null;

        //набор для скачивания
        public static List<DocumentMetaItem> attachList = null;
        
        static bool bNext = true;

        //текущий день загрузки
        static DateTime Day = DateTime.Now;

        static FastDocLoader()
        {
            attachList = new List<DocumentMetaItem>();
        }
        
        #region Распаковка архивов и формирование описателей в DocumentMeta
        ///// <summary>
        ///// пройтись по всей директории распаковать и переименовать все что есть/
        ///// новоявленные файлы прописать в DocumentMeta
        ///// </summary>
        //static void UnpackZipAttach()
        //{

        //    DocTools dt = new DocTools();
        //    dt.onAfterUnZipDoc += new DocTools.UnzipDoc(dt_onAfterUnzipDoc);
        //    dt.onAfterUnZipDocComplete +=new DocTools.UnZipDocComplete(dt_onAfterUnZipDocComplete);
        //    dt.UnzipFolder (config.TempDecompressFolder, TransportConfig.Instance.GetAttachStoreFolderPath(Day));
         
        //}

        ///// <summary>
        ///// Воткнуть в DocumentMeta описание файла
        ///// </summary>
        ///// <param name="fileName"></param>
        ///// <param name="filePref"></param>
        //private static void dt_onAfterUnzipDoc(string fileName, string filePref, int numberInZip,string fileExt)
        //{
        //    string sql = "generateDocumentMeta('{0}','{1}',{2},'{3}')";
        //    MongoTools t = new MongoTools();
        //    t.ExecuteScript(string.Format(sql, filePref, fileName, numberInZip, fileExt));
        //}
     
        //private static void dt_onAfterUnZipDocComplete(string zipFileName)
        //{
        //    TiDocInfo di = new TiDocInfo(zipFileName);             
        //    string sql = "deleteDocumentMeta('{0}',{1})";
        //    MongoTools t = new MongoTools();
        //    t.ExecuteScript(string.Format(sql,di.DocID ,di.Part));
        //    }

        
#endregion

        static void  LoadNextDoc()
        {
            string sf = string.Empty;

            #region  КОНЕЦ СПИСКА ЗАКАЧКИ
            if (attachList.Count == 0)
            {
                lock (attachList)
                {
                    //пришел другой поток после блокировки 
                    if (attachList.Count > 0)
                        return; 
                                    
                    //достаем невыкаченные документы
                    MongoTools t= new MongoTools ();                  
                    attachList = t.GetCollection<DocumentMetaItem>("getNotLoadedDocs(" + config.AttachDocPackSize + ","+Helper.Time.GetDateInMS(Day)+");");
                    if (attachList.Count == 0)
                    {
                        bNext = false;
                        return;
                    }
                    // attachList = t.GetCollection<DocumentMetaItem>("getNotLoadedDocs(1);");
                
                }
            }
            #endregion

            #region ВЫБОРКА ЗАПИСИ
            //выбрали запись для обработки 
            DocumentMetaItem currentDoc = null;
            lock (attachList)
            {
                currentDoc = attachList[0];
                attachList.RemoveAt(0);
            };

            try
            {
              
                DownloadDocFromUrl(currentDoc.URL, TransportConfig.Instance.GetAttachStoreFolderPath(Day) +@"\"+ currentDoc.PublicFileName);
                currentDoc.IsDownload = true;
                UpdateAttachItemRecord(currentDoc);
                Console.WriteLine(currentDoc.PublicFileName + ":ProcessedOK "+(DateTime .Now ).ToString ());
            }
            catch
            {
                Console.WriteLine(sf + ":ProcessedBAD");
            }
            #endregion
        }
       
        private static void ThreadRun()
        {
            do
            {
                FastDocLoader.LoadNextDoc();
                
            } while (bNext);

        }

        public  void Run(int ThreadCount, DateTime day )
        {
            Day = day;
            for (int i=0; i<ThreadCount;i++)
            {
                 new Thread(new ThreadStart(ThreadRun)).Start ();
            }            
        }

        /// <summary>
        /// Разархивировать если вдруг. Вернуть набор сформированных файлов
        /// </summary>
        /// <param name="fileName"></param>
        private static List<string>  UnzipDoc(string fileName)
        {
            List<string> result = new List<string>();

            FileInfo fi = new FileInfo(fileName);
            if (fi.Extension.ToUpper() == ".ZIP" || fi.Extension.ToUpper() == ".RAR")
            { 

            }
            return result;
        }
        
        private static void DownloadDocFromUrl(string URL, string fileName)
        {         
           if( File.Exists (fileName))
                    return ;

            System.Net.WebResponse response = GetResponce(URL);

            Stream responseStream = response.GetResponseStream();
           
            using (Stream file = File.OpenWrite(fileName))
            {
                CopyStream(responseStream, file);
            }
        }

        private static WebResponse GetResponce(string URL)
        {
            try
            {
                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL);

               // myHttpWebRequest.Proxy = new WebProxy(config.ProxyConfig.IP , config.ProxyConfig.Port);

               // myHttpWebRequest.Proxy.Credentials = new NetworkCredential(config.ProxyConfig.Login.Login, config.ProxyConfig.Login.Password);

                myHttpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)";

                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

                return myHttpWebResponse;
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            return null;
        }

        private static void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[10 * 1024];
            int len;
            while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                output.Write(buffer, 0, len);
            }
        }

        private static void UpdateAttachItemRecord(DocumentMetaItem itm)
        {
            Mongo mongo = new Mongo();
            IMongoDatabase db = mongo.GetDatabase("TI");
            try
            {
                mongo.Connect();
                db.Eval("updateDocumentMetaItem(" + itm.ToString() + ")");
            }
            finally
            {
                mongo.Disconnect();
            }
        }
    }

}
